package slu.appli.wodtimer.swing2;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.HeadlessException;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JSeparator;
import javax.swing.SwingUtilities;

import slu.appli.sound.interfaces.SoundPlayerInterface;
import slu.appli.wodtimer.WodTimerException;
import slu.appli.wodtimer.command.WodTimerUIControler;
import slu.appli.wodtimer.swing2.component.keypanel.XKeyPanel;
import slu.appli.wodtimer.swing2.component.keypanel.XKeyPanelInterface;
import slu.appli.wodtimer.swing2.component.text.XTextCombo;
import slu.appli.wodtimer.swing2.component.text.XTextInterface;
import slu.appli.wodtimer.swing2.cst.Commands;
import slu.appli.wodtimer.swing2.cst.Images;
import slu.appli.wodtimer.swing2.cst.Text4ComponentCst;
import slu.appli.wodtimer.swing2.logger.XTextLogger;
import slu.appli.wodtimer.swing2.progress.XProgressBasic;
import slu.appli.wodtimer.swing2.progress.XProgressPanelInterface;

public class WodTimerFrame
extends JFrame {
	private final WodTimerUIControler controler;
	private SoundPlayerInterface player = null;
	private final XTextLogger logger;

	private XTextInterface txt = new XTextCombo(); //  XTextBasic();
	private XKeyPanelInterface keyPanel = new XKeyPanel();
	private XProgressPanelInterface progressPanel = new XProgressBasic();
	
	private JPanel northPanel; 

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public WodTimerFrame(WodTimerUIControler controler)
			throws HeadlessException {
		super("WODTimer 2.0.0");
		this.controler = controler;
		this.logger = new XTextLogger();
		this.setIconImage(Images.ICON_APPLI.getImage());
		this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		this.addWindowListener(new InnerWindowListener());
	}

	public SoundPlayerInterface getPlayer() {
		return player;
	}

	public void setPlayer(SoundPlayerInterface player) {
		this.player = player;
	}

	public WodTimerUIControler getControler() {
		return controler;
	}

	public XTextLogger getLogger() {
		return logger;
	}
	
	public void build() {
		this.northPanel = new JPanel(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();
		c.insets = new Insets(0,2,0,2);
		JLabel label = new JLabel(Text4ComponentCst.LIB_REQUEST);
		label.setLabelFor(this.txt.getComponent());
		this.northPanel.add(label,c);
		c.fill = GridBagConstraints.HORIZONTAL;
		c.weightx = 1.0;
		this.northPanel.add(this.txt.getComponent(),c);
		c.fill = GridBagConstraints.NONE;
		c.weightx = 0;
		this.northPanel.add(this.keyPanel.getComponent(),c);
		JLabel frameMenu = new JLabel(Images.ICON_BTN_HOME);
		frameMenu.setComponentPopupMenu(this.getFramePopup(null));
		frameMenu.setToolTipText(Text4ComponentCst.TIP_WOD_MENU);
		this.northPanel.add(frameMenu,c);
		this.add(this.northPanel,BorderLayout.NORTH);
		this.add(this.logger,BorderLayout.CENTER);
		this.add(this.progressPanel.getComponent(),BorderLayout.SOUTH);
		this.keyPanel.addActionListener(new InnerActionListener());
		this.txt.addXTextListener(this.keyPanel.getTextListener());
		try {
			this.txt.load(XWodTimer.getContextFileName(this.txt));
		} catch (Exception e) {
			if (this.logger != null) this.logger.addException(e);
		}
		SwingUtilities.invokeLater(new InnerSwingLauncher());
		
	}
	
	private JPopupMenu getFramePopup(JPopupMenu popup) {
		if (popup == null) popup = new JPopupMenu();
		else popup.add(new JSeparator());
		ActionListener listener = new InnerActionListenerFrameMenu();
		JMenuItem item = new JMenuItem(Text4ComponentCst.MNU_HELP, Images.ICON_BTN_HELP);
		item.setActionCommand(Commands.CMD_HELP);
		item.addActionListener(listener);
		popup.add(item);
		item = new JCheckBoxMenuItem(Text4ComponentCst.MNU_TOP, Images.ICON_BTN_TOP);
		item.setActionCommand(Commands.CMD_TOP);
		item.addActionListener(listener);
		popup.add(item);
		item = new JCheckBoxMenuItem(Text4ComponentCst.MNU_SMALL, Images.ICON_BTN_SMALL);
		item.setActionCommand(Commands.CMD_SMALL);
		item.addActionListener(listener);
		popup.add(item);
		popup.add(new JSeparator());
		item = new JMenuItem(Text4ComponentCst.MNU_EXIT, Images.ICON_BTN_EXIT);
		item.setActionCommand(Commands.CMD_CLOSE);
		item.addActionListener(listener);
		popup.add(item);
		return popup;
	}
	
	private class InnerSwingLauncher implements Runnable {

		public void run() {
			WodTimerFrame.this.buildInSwing();
		}
		
	}
	
	private void buildInSwing() {
		this.pack();
		Dimension dim = this.getSize();
		dim.width = 550;
		dim.height += 200;
		this.setSize(dim);
		this.setLocationRelativeTo(null);
		this.setVisible(true);
		this.controler.setLogger(this.logger);
		this.controler.addWodTimerInformationListener(this.txt.getWodTimerInformationListener());
		this.controler.addWodTimerInformationListener(this.progressPanel.getWodTimerInformationListener());
		this.controler.addWodTimerInformationListener(this.keyPanel.getWodTimerInformationListener());
		this.player.play();
	}

	private String getHelpText() {
		StringBuilder sb = new StringBuilder();
		InputStream stream = WodTimerFrame.class.getClassLoader().getResourceAsStream(Text4ComponentCst.FILE_HELP);
		BufferedReader br = new BufferedReader(new InputStreamReader(stream));
		try {
			String line = br.readLine();
			while (line != null) {
				sb.append(line);
				sb.append("\n");
				line = br.readLine();
			}
		} catch (IOException e) {
			sb.append("");
		}
		return sb.toString();
	}
	
	private class InnerActionListener implements ActionListener {

		public void actionPerformed(ActionEvent arg0) {
			if (XKeyPanelInterface.ACT_PLAY.equals(arg0.getActionCommand())) {
				try {
					if (WodTimerFrame.this.logger != null) WodTimerFrame.this.logger.clear();
					String wod = WodTimerFrame.this.txt.getText().trim();
					int duration = (int) (WodTimerFrame.this.controler.calculate(wod) / 1000);
					WodTimerFrame.this.progressPanel.setDuration(duration);
					WodTimerFrame.this.controler.play(wod);
				}
				catch (Exception e) {
					WodTimerFrame.this.logger.addException(e);
				}
			}
			else if (XKeyPanelInterface.ACT_PAUSE.equals(arg0.getActionCommand())) {
				try {
					WodTimerFrame.this.controler.pause();
				} catch (WodTimerException e) {
					WodTimerFrame.this.logger.addException(e);
				}
			}
			else if (XKeyPanelInterface.ACT_STOP.equals(arg0.getActionCommand())) {
				try {
					WodTimerFrame.this.controler.stop();
				} catch (WodTimerException e) {
					WodTimerFrame.this.logger.addException(e);
				}
			}
			else if (XKeyPanelInterface.ACT_RESTART.equals(arg0.getActionCommand())) {
				try {
					WodTimerFrame.this.controler.restart();
				} catch (WodTimerException e) {
					WodTimerFrame.this.logger.addException(e);
				}
			}
		}
		
	}

	private class InnerWindowListener extends WindowAdapter {

		@Override
		public void windowClosing(WindowEvent arg0) {
			try {
				WodTimerFrame.this.txt.save(XWodTimer.getContextFileName(WodTimerFrame.this.txt));
			} catch (Exception e) {
				if (WodTimerFrame.this.logger != null) WodTimerFrame.this.logger.addException(e);
			}
			super.windowClosing(arg0);
		}
		
	}
	
	private class InnerActionListenerFrameMenu implements ActionListener {
		private Dimension prevDim = null;
		@Override
		public void actionPerformed(ActionEvent arg0) {
			if (Commands.CMD_HELP.equals(arg0.getActionCommand())) {
				if (WodTimerFrame.this.logger != null) {
					WodTimerFrame.this.logger.clear();
					WodTimerFrame.this.logger.addComment(WodTimerFrame.this.getHelpText());
					WodTimerFrame.this.pack();
				}
			}
			else if (Commands.CMD_TOP.equals(arg0.getActionCommand())) {
				WodTimerFrame.this.setAlwaysOnTop(((JCheckBoxMenuItem)arg0.getSource()).getState());
			}
			else if (Commands.CMD_SMALL.equals(arg0.getActionCommand())) {
				boolean small = ((JCheckBoxMenuItem)arg0.getSource()).getState();
				if(small) this.prevDim = WodTimerFrame.this.getSize();
				WodTimerFrame.this.logger.setVisible(!small);
				if(small) {
					WodTimerFrame.this.pack();
					WodTimerFrame.this.setResizable(false);
				}
				else {
					WodTimerFrame.this.setSize(this.prevDim);
					WodTimerFrame.this.setResizable(true);
				}
			}
			else if (Commands.CMD_CLOSE.equals(arg0.getActionCommand())) {
				WodTimerFrame.this.processEvent(new WindowEvent(WodTimerFrame.this, WindowEvent.WINDOW_CLOSING));
			}
		}
		
	}

}
